package com.heima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.heima.constants.Constants;
import com.heima.mapper.OrderMapper;
import com.heima.pojo.Order;
import com.heima.pojo.Partner;
import com.heima.pojo.vo.OrderPartnerVo;
import com.heima.pojo.vo.OrderVo;
import com.heima.service.OrderService;
import com.heima.service.PartnerService;
import com.heima.utils.PageResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 赵超
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    private final OrderMapper orderMapper;
    private final PartnerService partnerService;

    @Override
    public PageResult<OrderVo> search(Integer pageIndex, Integer pageSize, String orderNo, LocalDate startDate, LocalDate endDate) {

        //获取Order集合
        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        if (StringUtil.isNotEmpty(orderNo)) {
            lqw.eq(Order::getOrderNo, orderNo);
        } else if (ObjectUtils.isNotEmpty(startDate) && ObjectUtils.isNotEmpty(endDate)) {
            lqw.ge(Order::getCreateTime, endDate).le(Order::getCreateTime, startDate);
        }
        List<Order> orderList = orderMapper.selectList(lqw);

        //获取将Order复制给OrderVo
        List<OrderVo> orderVOList = new ArrayList<>();
        orderList.forEach(order -> {
            OrderVo orderVo = new OrderVo();
            BeanUtils.copyProperties(order, orderVo);
            orderVOList.add(orderVo);
        });

        //调用分页插件获取分页结果对象
        PageInfo<OrderVo> page = new PageInfo<>(orderVOList);
        long totalCount = page.getTotal();
        int totalPage = (int) ((totalCount + pageSize - 1) / pageSize);

        return new PageResult<>(pageIndex, pageSize, totalPage, totalCount, orderVOList);
    }


    @Override
    public String orderCount(Integer partnerId, LocalDateTime start, LocalDateTime end) {

        List<Order> orderList = getOrderList(partnerId, start, end);
        if (orderList.isEmpty()) {
            return "0";
        }
        return orderList.size() + "";
    }

    @Override
    public BigDecimal orderAmount(Integer partnerId, LocalDateTime start, LocalDateTime end) {

        List<Order> orderList = getOrderList(partnerId, start, end);
        if (orderList.isEmpty()) {
            return BigDecimal.ZERO;
        }

        //获取订单金额，单位：分
        BigDecimal orderAmountFen = orderList.stream()
                .filter(order -> ObjectUtils.isNotEmpty(order.getPayStatus()) && order.getPayStatus() == Constants.PAY_STATUS_PAID)
                .map(Order::getAmount)
                .map(BigDecimal::valueOf)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        //转成元
        return orderAmountFen.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
    }

    @Override
    public BigDecimal totalBill(Integer partnerId, LocalDateTime start, LocalDateTime end) {
        List<Order> orderList = getOrderList(partnerId, start, end);
        BigDecimal ratio = BigDecimal.ONE;
        if (ObjectUtils.isNotEmpty(partnerId)) {
            Integer ratioPercent = partnerService.getPartnerById(partnerId).getRatio();
            ratio = BigDecimal.valueOf(ratioPercent).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_UP);
        }
        //1. 获取订单金额（单位：分）
        BigDecimal totalAmountInFen = orderList
                .stream()
                .filter(order -> ObjectUtils.isNotEmpty(order.getPayStatus()) && order.getPayStatus() == Constants.PAY_STATUS_PAID)
                .map(Order::getAmount)
                .map(BigDecimal::valueOf)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 2. 计算分成金额（单位仍是分）
        BigDecimal sharedAmountInFen = totalAmountInFen.multiply(ratio);

        // 3. 转为“元”：除以 100
        BigDecimal sharedAmountInYuan = sharedAmountInFen.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);

        log.info("应分金额（元）: {}", sharedAmountInYuan);
        return sharedAmountInYuan;
    }

    @Override
    public PageResult<OrderPartnerVo> query(String partnerName,
                                            Integer pageIndex,
                                            Integer pageSize,
                                            LocalDate start,
                                            LocalDate end) {
        //转换前端传入日期数据
        LocalDateTime startTime = start.atStartOfDay();
        LocalDateTime endTime = end.atTime(23, 59, 59);

        //获取Partner
        Partner partner = partnerService.getOne(Wrappers.<Partner>lambdaQuery().eq(Partner::getName, partnerName));
        Integer partnerId = 1;
        if (ObjectUtils.isNotEmpty(partner)) {
            partnerId = partner.getId();
        }
        //获取分页结果
        Page<OrderPartnerVo> list = orderMapper.queryList(partnerId, startTime, endTime);
        PageHelper.startPage(pageIndex, pageSize);
        Integer totalPage = list.getPages();
        Long totalCount = list.getTotal();

        return new PageResult<>(pageIndex, pageSize, totalPage, totalCount, list);
    }

    private List<Order> getOrderList(Integer partnerId, LocalDateTime start, LocalDateTime end) {

        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        if (ObjectUtils.isNotEmpty(start) && ObjectUtils.isNotEmpty(end)) {
            lqw.ge(Order::getCreateTime, start).le(Order::getCreateTime, end);
        } else if (ObjectUtils.isNotEmpty(partnerId)) {
            lqw.eq(Order::getOwnerId, partnerId);
        }

        return orderMapper.selectList(lqw);
    }


}
